package com.mskj.zxmy.service.serviceImpl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.date.DateUtil;
import com.mskj.zxmy.common.BusinessException;
import com.mskj.zxmy.dto.*;
import com.mskj.zxmy.entity.BarCodeManagementDetails;
import com.mskj.zxmy.entity.BarcodeManagement;
import com.mskj.zxmy.entity.CKDan;
import com.mskj.zxmy.entity.XssalesDispatchDetails;
import com.mskj.zxmy.mapper.MaterialInfoMapper;
import com.mskj.zxmy.mapper.OutboundOrderMapper;
import com.mskj.zxmy.mapper.StockInMapper;
import com.mskj.zxmy.mapper.UserMapper;
import com.mskj.zxmy.service.OutboundOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

@Service
public class OutboundOrderServiceImpl implements OutboundOrderService {

    @Autowired
    private OutboundOrderMapper outboundOrderMapper;
    @Autowired
    private StockInMapper stockInMapper;

    @Autowired
    private MaterialInfoMapper materialInfoMapper;
    @Autowired
    private UserMapper userMapper;

    /**
     * 查询发货单列表
     *
     * @return
     */
    @Override
    public List<ShipmentNoticeDTO> outboundOrderList() {
        return outboundOrderMapper.outboundOrderList();

    }

    /**
     * 条件筛选发货通知单
     *
     * @param params
     * @return
     */
    @Override
    public List<ShipmentNoticeDTO> filterShipmentNotices(Map<String, Object> params) {
        return outboundOrderMapper.selectShipmentNoticeList(params);
    }

    @Override
    public PageInfo<ShipmentNoticeDTO> outboundOrderListWithPage(OutboundOrderListQueryDTO query) {
        PageHelper.startPage(query.getPageNum(), query.getPageSize());
        List<ShipmentNoticeDTO> result = outboundOrderMapper.selectShipmentNoticeListByQuery(query);
        for (ShipmentNoticeDTO shipmentNoticeDTO : result) {
            shipmentNoticeDTO.setDateTitle1(shipmentNoticeDTO.getClientId() + " " + shipmentNoticeDTO.getClientName());
        }
        return new PageInfo<>(result);
    }

    /**
     * 创建出库单
     *
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, CKDan> createOutbound() {
        String datePart = DateUtil.format(DateUtil.date(), "yyyyMMdd");

        /*// 生成单据号（RK开头）
//        String billNo = generateBillNo(datePart);
//             生成批次号及出库单号（CK开头）
//            String bailoutNumber = createBailoutNumber(datePart);*/

        CKDan Outbound = CKDan
                .builder()
//                .cashiersNumber(newcashiersNumber)
                .collectionDate(LocalDate.now())
                .poolType("销售出库")
//                    .cashiersNumber(cashiersNumber) // 使用独立生成的批次号
                .operator(stockInMapper.getUserName((String) StpUtil.getLoginId()))
                .approvalStatus("DRAFT")
                .created(LocalDate.now())
                .build();

        // 自动生成cashiersNumber
        String datePartForRepository = new SimpleDateFormat("yyyyMMdd").format(new Date());
        String maxcashiersNumber = outboundOrderMapper.selectMaxcashiersNumberByDate(datePartForRepository);
        String newcashiersNumber;
        if (maxcashiersNumber == null) {
            newcashiersNumber = "CK" + datePartForRepository + "0001";
        } else {
            String seqStr = maxcashiersNumber.substring(maxcashiersNumber.length() - 4);
            int seq = Integer.parseInt(seqStr) + 1;
            newcashiersNumber = "CK" + datePartForRepository + String.format("%04d", seq);
        }
        Outbound.setCashiersNumber(newcashiersNumber);

        Map<String, CKDan> result = new HashMap<>();
        result.put("Outbound", Outbound);
        return result;
    }

    @Override
    public List<XssalesDispatchDetails> getDispatchDetailsByShipmentOrderNumber(String shipmentOrderNumber) {
        // 1. 查主表，拿到 salesAndDispatchDetails 字段
        String idsStr = outboundOrderMapper.getSalesAndDispatchDetailsIdsByOrderNumber(shipmentOrderNumber);
        if (idsStr == null || idsStr.isEmpty()) {
            return java.util.Collections.emptyList();
        }
        // 2. 解析成 List<Integer>
        idsStr = idsStr.replaceAll("\\[|\\]", ""); // 去掉中括号
        java.util.List<Integer> ids = java.util.Arrays.stream(idsStr.split(","))
                .map(String::trim)
                .filter(s -> !s.isEmpty())
                .map(Integer::parseInt)
                .collect(java.util.stream.Collectors.toList());
        // 3. 查子表
        return outboundOrderMapper.getDispatchDetailsByIds(ids);

    }

    /**
     * \
     * 保存出入库
     *
     * @param dto
     * @return
     */
   /* @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveCKDanWithDetails(CKDanSaveDTO dto) {
        // 1. 保存主表（不赋值id，让数据库自增）
        CKDan ckDan = new CKDan();
        ckDan.setCashiersNumber(dto.getCashiersNumber());
        ckDan.setPoolType("销售出库");
        ckDan.setOperator("系统管理员");
//      ckDan.setCollectionDate(LocalDate.now());
        ckDan.setRemarks(dto.getRemarks());
        ckDan.setCashiersNumber(dto.getCashiersNumber());
        ckDan.setApprovalStatus("已通过");
//      ckDan.setAssociatedConsignmentOrder(dto.getAssociatedConsignmentOrder());//出库单
        int mainRes = outboundOrderMapper.insertCKDan(ckDan);
        if (mainRes <= 0) return false;
        // 2. 批量保存明细，使用主表自增id
        List<CKDanDetailSaveDTO> details = dto.getShowMeTheDetails();
        if (details != null && !details.isEmpty()) {
            for (CKDanDetailSaveDTO detail : details) {
                detail.setProductInformation(detail.getProductInformation());
                detail.setBatchNumber(detail.getBatchNumber());
                detail.setNumberOfReleases(detail.getNumberOfReleases());
                detail.setLinkToList(ckDan.getId());
                outboundOrderMapper.insertCKDanDetail(detail);
            }
        }
        return true;
    }*/
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveCKDanWithDetails(CKDanSaveDTO dto) {
        // 1. 主表查重
        CKDanSaveDTO exist = outboundOrderMapper.getCKDanByCashiersNumber(dto.getCashiersNumber());
        int mainRes = 1;
        int mainId;
        if (exist == null) {
            // 不存在，插入主表
            CKDan ckDan = new CKDan();
            ckDan.setCashiersNumber(dto.getCashiersNumber());
            ckDan.setPoolType("销售出库");
            if (StpUtil.getLoginId() != null) {
                ckDan.setOperator(StpUtil.getLoginId().toString());
            }

            ckDan.setCreated(LocalDate.now());
            ckDan.setRemarks(dto.getRemarks());
            ckDan.setApprovalStatus("已通过");
            ckDan.setReconciliationStatus("未对账");
            ckDan.setCreated(LocalDate.now());
            ckDan.setClientInformation(outboundOrderMapper.getClientByAssociatedConsignmentOrder(dto.getAssociatedConsignmentOrder()));
            ckDan.setAssociatedConsignmentOrder(dto.getAssociatedConsignmentOrder());
            mainRes = outboundOrderMapper.insertCKDan(ckDan);
            mainId = ckDan.getId();
        } else {
            // 已存在，直接用主表id
            mainId = exist.getId();
        }
        if (mainRes <= 0) return false;

        // 2. 明细查重与合并
        List<CKDanDetailSaveDTO> details = dto.getShowMeTheDetails();
        if (details != null && !details.isEmpty()) {
            for (CKDanDetailSaveDTO detail : details) {
                // 2.1 查重：同一出库单、同一商品、同一批次
                detail.setAssociatedConsignmentOrder(detail.getAssociatedConsignmentOrder());
                CKDanDetailSaveDTO existDetail = outboundOrderMapper.getDetailByMainIdAndProductAndBatch(
                        mainId, String.valueOf(detail.getProductInformation()), detail.getBatchNumber()
                );
                if (existDetail != null) {
                    // 2.2 已存在，合并数量
                    outboundOrderMapper.updateDetailNumberOfReleases(Integer.parseInt(String.valueOf(existDetail.getId())), detail.getNumberOfReleases());
                } else {
                    // 2.3 不存在，插入新明细
                    detail.setLinkToList(mainId);
                    detail.setProductInformation(outboundOrderMapper.getProductInfoOfId(detail.getId()));
                    outboundOrderMapper.insertCKDanDetail(detail);
                }
            }
        }

        // 3. 校验库存并扣减库存
        if (details != null && !details.isEmpty()) {
            for (CKDanDetailSaveDTO detail : details) {
                int productId = detail.getProductInformation();
                String batchNumber = detail.getBatchNumber();
                int outNumber = detail.getNumberOfReleases();
                Integer stock = outboundOrderMapper.getStockByProductAndBatch(String.valueOf(productId), batchNumber);
                if (stock == null || stock < outNumber) {
                    throw new BusinessException("产品【" + detail.getProductName() + "】批次【" + batchNumber + "】库存不足，当前库存：" + (stock == null ? 0 : stock));
                }
            }
            for (CKDanDetailSaveDTO detail : details) {
                outboundOrderMapper.decreaseStock(
                        String.valueOf(detail.getProductInformation()),
                        detail.getId(),
                        detail.getNumberOfReleases()
                );
            }
        }

        // 3. 计算总出库数量并更新主表
        // int totalOutboundQuantity = 0;
        // if (details != null && !details.isEmpty()) {
        //     for (CKDanDetailSaveDTO detail : details) {
        //         if (detail.getNumberOfReleases() != null) {
        //             totalOutboundQuantity += detail.getNumberOfReleases();
        //         }
        //     }
        // }

        // 用明细表实际汇总数量更新主表totalNumber
        int totalNumber = outboundOrderMapper.sumDetailNumberOfReleases(mainId);
        outboundOrderMapper.updateTotalNumberById(mainId, totalNumber);

        return true;
    }

    /**
     * 查询出库单列表
     *
     * @return
     */

    @Override
    public PageInfo<CKDanListDTO> getCKDanListWithPage(CKDanListQueryDTO query) {
        PageHelper.startPage(query.getPageNum(), query.getPageSize());
        List<CKDanListDTO> list = outboundOrderMapper.getCKDanList(query);
        for (CKDanListDTO ckDan : list) {
            ckDan.setOperator(outboundOrderMapper.getAssociatedSuppliersName(ckDan.getCashiersNumber()));
        }
        return new PageInfo<>(list);
    }

    /**
     * 根据出库单查询出库单明细
     *
     * @param cashiersNumber
     * @return
     */
    @Override
    public CKDanSaveDTO getCKDanListDetails(String cashiersNumber) {
        // 1. 查主表
        CKDanSaveDTO main = outboundOrderMapper.getCKDanByCashiersNumber(cashiersNumber);
//        List<Integer> showMeTheDetailss = main.getShowMeTheDetailss();
        if (main == null) return null;
        // 2. 查子表
//        for (Integer list :showMeTheDetailss){
//            outboundOrderMapper.getCKDanDetailsByMainId(list);
//        }
        List<CKDanDetailSaveDTO> details = outboundOrderMapper.getCKDanDetailsByMainId(main.getId());
        int totalReleases = 0;
        for (CKDanDetailSaveDTO detail : details) {
            ProductDetailDTO productDetailDTO = outboundOrderMapper.getProductInfo(detail.getId());
            detail.setBrand(productDetailDTO.getBrand());
            detail.setProductNumber(productDetailDTO.getProductNumber());
            detail.setProductName(productDetailDTO.getProductName());
            detail.setEnvironmentalProtectionLevel(productDetailDTO.getEnvironmentalProtectionLevel());
            detail.setProductSpecifications(productDetailDTO.getTypeOfProduct() + " " + productDetailDTO.getMaterialCategory());

            totalReleases += detail.getNumberOfReleases();
        }
        // 3. 封装DTO
        CKDanSaveDTO dto = new CKDanSaveDTO();
        // ...拷贝主表字段...
        dto.setCashiersNumber(main.getCashiersNumber());
        dto.setPoolType(main.getPoolType());
        dto.setCollectionDate(LocalDate.now());
        dto.setOperator(stockInMapper.getUserNameBymenmberId(main.getOperator()));
        dto.setRemarks(main.getRemarks());
        dto.setShowMeTheDetails(details);
        dto.setTotalNumber(totalReleases);
        return dto;
    }

    /**
     * 根据销售发货单查询出库单
     *
     * @param xsd
     * @return
     */
    @Override
    public List<CKDanSaveDTO> getCKDanDetailsByXSDan(String xsd) {
        List<CKDanSaveDTO> ckDanDetailsByXSDan = stockInMapper.getCKDanDetailsByXSDan(xsd);
        for (CKDanSaveDTO ckDanSaveDTO : ckDanDetailsByXSDan) {
            ckDanSaveDTO.setOperator(outboundOrderMapper.getAssociatedSuppliersName(ckDanSaveDTO.getCashiersNumber()));
        }
        return ckDanDetailsByXSDan;
    }

    @Override
    public List<CKDanListDTO> filterCKDanList(Map<String, Object> params) {
        List<CKDanListDTO> filterCKDanList = outboundOrderMapper.filterCKDanList(params);
        for (CKDanListDTO ckDanList : filterCKDanList) {
            ckDanList.setOperator(outboundOrderMapper.getAssociatedSuppliersName(ckDanList.getCashiersNumber()));
        }
        return filterCKDanList;
    }

    /**
     * 生成批次号（PC+YYYYMMDD+两位数字）
     */
//        private String createBailoutNumber(String datePart) {
//            String maxBatchNo = outboundOrderMapper.selectMaxBatchNo(datePart);
//            int seq = 1;
//            if (maxBatchNo != null) {
//                String seqPart = maxBatchNo.substring(10); // 提取PC后面的两位数字
//                seq = Integer.parseInt(seqPart) + 1;
//            }
//            return "PC" + datePart + String.format("%02d", seq);
//        }

    /*    出库确认*/
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void confirmOutbound(BarcodeManagement barcode) {
        BarcodeManagement barcodeManagement = outboundOrderMapper.getBarcodeManagementBycode(barcode.getId());
        // 1. 校验库存
        Integer number = outboundOrderMapper.getStockByDetailId(barcodeManagement.getId());
        if (number == null || number < barcode.getNumber()) {
            throw new RuntimeException("库存不足，当前库存：" + (number == null ? 0 : number));
        }

        // 2. 扣减批次数量
        outboundOrderMapper.decreaseBarcodeManagement(barcode.getId(), barcode.getNumber());
        BarCodeManagementDetails barCodeManagementDetails = new BarCodeManagementDetails();
//        barCodeManagementDetails
//
//        stockInMapper.savaBarCodeManagementDetails();

//        outboundOrderMapper.decreaseStock(
//            String.valueOf(barcode.getProductName()),
//                barcode.getId(),
//                barcode.getNumber()
//        );
//
        // 3. 新增出库明细
        CKDanDetailSaveDTO detail = outboundOrderMapper.getOutDetail(barcode.getId());
        detail.setProductInformation(outboundOrderMapper.getProductInfoOfId(barcode.getId()));
        outboundOrderMapper.insertCKDanDetail(detail);
    }


    /**
     * 出库明细相关接口
     *
     * @param documentStatus
     * @return
     */
    @Override
    public List<ck02CheckoutFormCheckout> getOutboundDetails(String documentStatus) {
        List<ck02CheckoutFormCheckout> result = outboundOrderMapper.getOutboundDetails(documentStatus);
        loadProcessingDetailedAssociatedIds(result);
        return result;
    }

    @Override
    public ck02CheckoutFormCheckout getOutboundDetailById(String detailId) {
        ck02CheckoutFormCheckout detail = outboundOrderMapper.selectOutboundDetailById(detailId);
        if (detail != null) {
            detail.setSynchronisingFolderFailedSS(userMapper.findNickByMemberId(detail.getSynchronisingFolderFailedSS()));
            detail.setLinkOutList(outboundOrderMapper.getLinkOutListByCashiersNumber(detail.getLinkOutList()));
            ProductDetailDTO product = stockInMapper.getProductInfoByNumber(detail.getProductInformation());
            if (product != null) {
                detail.setProductInfo(
                        product.getProductName() + " "
                                + product.getMaterialCategory() + " "
                                + product.getEnvironmentalProtectionLevel() + " "
                                + product.getBrand()
                );
            } else {
                detail.setProductInfo("未知物料");
            }
        }
        return detail;
    }

    /**
     * 条件筛选出库明细
     *
     * @param query
     * @return
     */
    @Override
    public PageInfo<ck02CheckoutFormCheckout> filterOutboundDetailsWithPage(OutboundDetailQueryDTO query) {
        if (query.getDocumentStatus() == null || query.getDocumentStatus().trim().isEmpty()) {
            throw new IllegalArgumentException("出库状态（documentStatus）不能为空");
        }

        List<String> productNumbers = materialInfoMapper.selectProductNumbersByFilter(
                query.getProductName(),
                query.getProductSpecifications(),
                query.getMaterialCategory(),
                query.getBrand()
        );
        if (productNumbers.isEmpty()) {
            return new PageInfo<>(Collections.emptyList());
        }
        PageHelper.startPage(query.getPageNum(), query.getPageSize());
        List<ck02CheckoutFormCheckout> result = outboundOrderMapper.selectStockInByProductNumbers(
                query.getCashiersNumber(),
                productNumbers,
                query.getDocumentStatus());
        loadProcessingDetailedAssociatedIds(result);
        return new PageInfo<>(result);
    }

    /**
     * 加载出库明细关联的详细信息
     *
     * @param result 出库明细列表，需要填充关联信息的明细数据
     */
    private void loadProcessingDetailedAssociatedIds(List<ck02CheckoutFormCheckout> result) {
        for (ck02CheckoutFormCheckout detail : result) {
            detail.setLinkOutList(outboundOrderMapper.getLinkOutListByCashiersNumber(detail.getLinkOutList()));
            detail.setSynchronisingFolderFailedSS(userMapper.findNickByMemberId(detail.getSynchronisingFolderFailedSS()));
            ProductDetailDTO product = stockInMapper.getProductInfoByNumber(detail.getProductInformation());
            if (product != null) {
                detail.setProductInfo(
                        product.getProductName() + " "
                                + product.getMaterialCategory() + " "
                                + product.getEnvironmentalProtectionLevel() + " "
                                + product.getBrand()
                );
            } else {
                detail.setProductInfo("未知物料");
            }
        }
    }
}

